﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using log4net;
using McsUtility;

namespace MinerManager.Forms
{
	public partial class MinerHashrate : DevExpress.XtraEditors.XtraForm
	{
		ILog logger = LogManager.GetLogger(typeof(Program));
		private Common.AgentComponent Agent = null;

		private int MinerId = 0;
		private string MinerName = string.Empty;
		private string FirstCurrencyName = string.Empty;
		private string SecondCurrencyName = string.Empty;
		private bool TimerRefreshingHashrate = false;//计时器正在刷新算力
		private Timer RefreshHashrate = new Timer
		{
			Interval = 1000 * 5,
			Enabled = true
		};

		public event EventHandler<EventArgs> OnClose;

		public MinerHashrate(Common.AgentComponent agent, int minerId, string minerName, string firstCurrencyName, string secondCurrencyName)
		{
			InitializeComponent();
			this.Agent = agent;
			this.MinerId = minerId;
			this.MinerName = minerName;
			this.FirstCurrencyName = firstCurrencyName;
			this.SecondCurrencyName = secondCurrencyName;
		}

		#region 窗体事件

		private void MinerHashrate_Load(object sender, EventArgs e)
		{
			this.Agent.OnReceive += new EventHandler<RcvEventArgs>(Agent_OnReceive);

			Label_MinerName.Text = this.MinerName;

			//刷新数据
			RequestMinerHashrate();
			Action<object, EventArgs> refreshTick = delegate (object obj, EventArgs args)
			{
				RequestMinerHashrate();
			};
			
			this.RefreshHashrate.Tick += new EventHandler(refreshTick);
			this.RefreshHashrate.Start();
		}

		private void MinerHashrate_FormClosing(object sender, FormClosingEventArgs e)
		{
			this.RefreshHashrate.Enabled = false;
			this.Agent.OnReceive -= new EventHandler<RcvEventArgs>(Agent_OnReceive);
			this.OnClose?.Invoke(this, new EventArgs());
		}

		#endregion

		#region void Agent_OnReceive(object sender, RcvEventArgs e)

		private void Agent_OnReceive(object sender, RcvEventArgs e)
		{
			var proto = ProtocolHelper.GetProtoType(e.Buffer, body: out byte[] body);
			string json = System.Text.Encoding.UTF8.GetString(body);

			if (proto == ProtoType.NodeServerMinerManagerGetRedisData)
			{
				List<McsUtility.Models.RedisDataModel> result = ProtocolHelper.ReadPackageBody<List<McsUtility.Models.RedisDataModel>>(body);
				LoadMinerHashrate(result);
			}
		}

		#endregion



		#region void RequestMinerHashrate() 请求算力信息。

		private delegate void DelegateRequestMinerHashrate();

		/// <summary>
		/// 请求算力信息。
		/// </summary>
		private void RequestMinerHashrate()
		{
			//设置是否允许刷新算力信息，不允许刷新时终止执行
			if (!this.TimerRefreshingHashrate)
				this.TimerRefreshingHashrate = true;
			else
				return;

			if (this.InvokeRequired)
			{
				DelegateRequestMinerHashrate d = new DelegateRequestMinerHashrate(RequestMinerHashrate);
				this.BeginInvoke(d);
			}
			else
			{
				//发送数据
				if (this.Agent.IsStarted)
				{
					byte[] bytes = ProtocolHelper.WritePackage<int[]>(ProtoType.MinerManagerGetRedisData, new int[] { this.MinerId });
					this.Agent.AgentSend(bytes);
				}
			}
		}

		#endregion

		#region void LoadMinerHashrate(List<McsUtility.Models.RedisDataModel> infos) 读取并在矿机列表中显示算力。

		private delegate void DelegateLoadMinerHashrate(List<McsUtility.Models.RedisDataModel> infos);

		/// <summary>
		/// 读取并在矿机列表中显示算力。
		/// </summary>
		private void LoadMinerHashrate(List<McsUtility.Models.RedisDataModel> infos)
		{
			if (this.InvokeRequired)
			{
				DelegateLoadMinerHashrate d = new DelegateLoadMinerHashrate(LoadMinerHashrate);
				this.BeginInvoke(d, infos);
			}
			else
			{
				if (infos.Count > 0 && !string.IsNullOrWhiteSpace(infos[0].RedisData))
				{
					Models.MinerRedisData infoRedisData = TomNet.Utility.Data.JsonHelper.FromJson<Models.MinerRedisData>(infos[0].RedisData);
					Models.MinerHashrateAndTmpFanModel infoHashrate = infoRedisData.ConvertHashrate();
					
					First_CurrencyName.Text = this.FirstCurrencyName;
					First_Hashrate.Text = infoHashrate.FirstTotalHashrate;
					First_Success.Text = infoHashrate.FirstSuccess;
					First_Failure.Text = infoHashrate.FirstFailure;

					Second_CurrencyName.Text = this.SecondCurrencyName;
					Second_Hashrate.Text = infoHashrate.SecondTotalHashrate;
					Second_Success.Text = infoHashrate.SecondSuccess;
					Second_Failure.Text = infoHashrate.SecondFailure;
					
					List<HashrateDetailModel> infosDetail = new List<HashrateDetailModel>();
					int listCount = new List<int> { infoHashrate.FirstHashrate.Count, infoHashrate.SecondHashrate.Count, infoHashrate.Temps.Count, infoHashrate.Fans.Count }.Max();
					for(int i = 0; i < listCount; i++)
					{
						infosDetail.Add(new HashrateDetailModel
						{
							Number = (i + 1).ToString(),
							FirstHashrate = infoHashrate.FirstHashrate.Count > i ? infoHashrate.FirstHashrate[i] : "-",
							SecondHashrate = infoHashrate.SecondHashrate.Count > i ? infoHashrate.SecondHashrate[i] : "-",
							Temp = infoHashrate.Temps.Count > i ? infoHashrate.Temps[i] : "-",
							Fan = infoHashrate.Fans.Count > i ? infoHashrate.Fans[i] : "-"
						});
					}
					TableList.DataSource = infosDetail;
				}

				//设置计数器未执行刷新算力
				this.TimerRefreshingHashrate = false;
			}
		}

		#endregion

		#region class HashrateDetailModel 算力明细实体。

		/// <summary>
		/// 算力明细实体。
		/// </summary>
		private class HashrateDetailModel
		{
			/// <summary>
			/// 编号
			/// </summary>
			public string Number { get; set; }

			/// <summary>
			/// 主币算力
			/// </summary>
			public string FirstHashrate { get; set; }

			/// <summary>
			/// 辅币算力
			/// </summary>
			public string SecondHashrate { get; set; }

			/// <summary>
			/// 温度
			/// </summary>
			public string Temp { get; set; }

			/// <summary>
			/// 风扇
			/// </summary>
			public string Fan { get; set; }
		}

		#endregion
	}
}